package com.tensai.study.新特性.JDK8.函数式编程;


import org.junit.Test;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest {

    private static final Random rand = new Random();

    void println(Object val) {
        System.out.println(val);
    }

    static class Group {

        int    id;
        String name;

        @Override
        public String toString() {
            return "Group [id=" + id + ", name=" + name + "]";
        }

    }

    static class User {

        int    id;
        int    age;
        int    groupId;
        String groupName;
        String name;
        int    money;

        @Override
        public String toString() {
            return "User [id=" + id + ", age=" + age + ", name=" + name + ", money=" + money + "]";
        }

        public int getId() {
            return id;
        }

        public int getGroupId() {
            return groupId;
        }

        public int getMoney() {
            return money;
        }

    }

    private List<User> getUserAll() {
        int size = rand.nextInt(100);
        Map<Integer, User> users = new HashMap<>();
        String[] names = new String[] { "赵", "孙", "李", "王", "刘" };
        for (int i = 0; i < size; i++) {
            User user = new User();
            user.id = rand.nextInt(size);
            user.age = rand.nextInt(150);
            user.groupId = rand.nextInt(5);// 用户属于5个组
            user.groupName = user.groupId + "- Name";
            user.name = rand.nextBoolean() ? names[rand.nextInt(names.length)] : null;
            user.money = rand.nextInt(1000);
            users.put(user.id, user);
        }
        return new ArrayList<>(users.values());
    }

    public static void main(String[] args) {
        List<String> strings = Stream.of("C", "D", "A", "B", null)
                .filter(Objects::nonNull)
                .sorted()
                .collect(Collectors.toList());

        System.out.println(strings);
    }

    @Test
    public void testFilterConditiom() {
        //
        List<User> users = getUserAll();
        // 更复杂的条件
        List<User> userNameEmptys = users.stream().filter(user -> {
            // 找出名称为空的用户
            if (null != user.name) {
                return false;
            }
            // 找出名称为空的用户并且年龄大于等于50的用户
            if (user.age < 50) {
                return false;
            }
            // 找出名称为空的用户并且年龄大于等于50，并且用户金额小于30的用户
            return user.money < 30;
            // 符合条件的用户
        }).collect(Collectors.toList());
        //
        println("符合条件的用户集合个数：" + userNameEmptys.size());
        userNameEmptys.forEach(user -> {
            println("名称为空：" + user);
        });

    }

    @Test
    public void testMapOfUserToIds() {
        //
        List<User> users = getUserAll();
        // 找出用户ID集合
        List<Integer> userIds = users.stream().filter(user -> user.id > 0).map(user -> user.id).collect(Collectors
                .toList());
        //
        println("用户ID的集合个数：" + userIds.size());
        userIds.stream().forEach(id -> {
            println("ID：" + id);
        });

    }

    @Test
    public void testToMap() {
        //
        List<User> users = getUserAll();
        // 找出用户ID集合
        Map<Integer, User> userMap = users.stream().filter(user -> user.id > 0).collect(Collectors.toMap(User::getId,
                Function.identity()));
        //
        println("用户ID的集合个数：" + userMap.size());
        userMap.values().forEach(user -> {
            println("User：" + user);
        });

    }

    @Test
    public void testToMapConvert() {
        //
        List<User> users = getUserAll();
        // 找出用户ID集合
        List<Group> groups = users.stream().filter(user -> user.id > 0).map(user -> {
            Group g = new Group();
            g.id = user.groupId;
            g.name = user.groupName;
            return g;
        }).collect(Collectors.toList());
        //
        println("用户ID所属组集合个数：" + groups.size());
        groups.stream().forEach(group -> {
            println("Group：" + group);
        });

    }

    @Test
    public void testGroupingBy() {
        //
        // 找出组用户集合
        Map<Integer, List<User>> groupUserMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
                .groupingBy(User::getGroupId));
        //
        println("用户总共属于组个数：" + groupUserMap.size());
        groupUserMap.values().forEach(listUser -> {
            println("ListUser：" + listUser);
        });
        //
        Map<Integer, Long> groupCountsMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
                .groupingBy(User::getGroupId, Collectors.counting()));
        groupCountsMap.entrySet().forEach(group -> {
            println("组ID：" + group.getKey() + "，个数：" + group.getValue());
        });
        //
        Map<Integer, Integer> groupUserMoneyMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
                .groupingBy(User::getGroupId, Collectors.summingInt(User::getMoney)));
        groupUserMoneyMap.entrySet().stream().forEach(group -> {
            println("组ID：" + group.getKey() + "，组用户所有金额：" + group.getValue());
        });
        //
    }

    @Test
    public void testCollectingAndThen() {
        //
        List<User> users = getUserAll();
        println("用户个数：" + users.size());
        users.addAll(getUserAll());
        println("添加后用户个数：" + users.size());

        // 找出组用户集合
        List<User> unique = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(User::getId))), ArrayList::new));
        //
        println("去除重复后用户个数：" + unique.size());
        //

    }

    @Test
    public void testMapSum() {
        //
        Stream<String> s = Stream.of("1", "2", "3", "4", "4");
        //
        long ans = s.collect(Collectors.counting());
        println("个数：" + ans);
        //
        s = Stream.of("1", "2", "3", "4", "4");
        Set<String> set = s.collect(Collectors.toCollection(TreeSet::new));
        println("经Set后个数：" + set.stream().collect(Collectors.counting()));
        //
        s = Stream.of("1", "2", "3", "4", "4");
        String joined = s.map(Object::toString).collect(Collectors.joining(", "));
        println("joined : " + joined);
        // 用户金额总和
        int sum = getUserAll().stream().mapToInt(User::getMoney).sum();
        println("用户金额总和 : " + sum);
        //
        sum = getUserAll().stream().mapToInt(User::getMoney).sum();
        println("用户金额总和 : " + sum);
        //
    }

    @Test
    public void testFilterNameEmpty() {
        //
        List<User> users = getUserAll();
        // 找出name为空的用户
        List<User> userNameEmptys = users.stream()
                .filter(user -> user.name == null).collect(Collectors.toList());
        //
        println("名称为空的集合个数：" + userNameEmptys.size());
        userNameEmptys.forEach(user -> {
            println("名称为空：" + user);
        });

    }

    @Test
    public void t() {
        Stream.of("one", "two", "three", "four")
                .filter(e -> e.length() > 3)
                .peek(e -> System.out.println("Filtered value: " + e))
                .map(String::toUpperCase)
                .peek(e -> System.out.println("Mapped value: " + e))
                .collect(Collectors.toList());

    }

}
